﻿Imports System.Text
Imports System.Math

Partial Public Class TimeSheetExplorer
    Public ClientMode As Boolean = True
    Public TimeSheetID As Guid
    Public EmplID? As Guid
    Private DateWorked? As Date = Date.Today
    Private WithEvents LookupEdit As GridLookUpEdit

    Private ProjectId As Guid?
    Private ProductId As Guid?
    Private Discount As Decimal?
    Private DiscountedRate As Decimal?
    Private ProjectRessourceRate As Decimal?

    Public CurrentRow As DataRow

    'Public Sub Init_TreeActionOptionList(sender As Object, e As EventArgs)

    'End Sub


    Public Sub TreeActionOptionListLoad()
        Me.MetaControlTreeListActionOptionList.Add(New ActionOption("TimeSheetHeader", "ACT_00164", "Create Timesheet Header", AddressOf Timesheet_CreateHeader, True, True))
    End Sub

    Public Overridable Sub RowNotify(sender As Object, e As RowObjectEventArgs)
        Dim aDataRow As DataRow = TryCast(e.Row, DataRowView).Row
        If aDataRow IsNot Nothing Then
            ' La MQ a pas le StatusID_FK a finir
            'If aDataRow.IsColumnChanged("StatusID_FK") Then
            '    Me.aGridControl.SaveCommand()
            '    'MessageWindow.ShowMessage("Notify on Row:" + aDataRow.Table.TableName)
            'End If
        End If
    End Sub

    Public Overridable Sub ValidateMasterRow(ByVal sender As Object, ByVal e As DevExpress.XtraGrid.Views.Base.ValidateRowEventArgs)
        Dim row As DataRow = CType(e.Row, DataRowView).Row
        Using plTs As SystemBoxSDK.PL.TSMSDK.TimeSheet_PL = New SystemBoxSDK.PL.TSMSDK.TimeSheet_PL()
            plTs.ValidateRow(row)
        End Using
    End Sub
    Public Overridable Sub ValidateDetailRow(ByVal sender As Object, ByVal e As DevExpress.XtraGrid.Views.Base.ValidateRowEventArgs)
        Dim row As DataRow = CType(e.Row, DataRowView).Row
        Using plTsh As SystemBoxSDK.PL.TSMSDK.TimeSheetHour_PL = New SystemBoxSDK.PL.TSMSDK.TimeSheetHour_PL()
            plTsh.ValidateRow(row)
            'Pour le Middleman... Regle SCIEF
            If row("WorkDescription").ToString.Length < 4 Then
                'TODO: Get metastring ex:
                row.SetColumnError("WorkDescription", "Please Complete Your Work Description, 8 Characters Minimum")
            End If
            If IsDBNull(row("ProjectResourceId_FK")) Then
                'TODO: Get metastring ex:
                row.SetColumnError("ProjectResourceId_FK", "Mandatory")
            End If
        End Using

        ''ici on remet les valeurs a nothing pour ne pas overwriter les valeur déjà entrer pour les lignes suivante - aleblanc
        'ProjectRessourceRate = Nothing
        'DiscountedRate = Nothing
        'Discount = Nothing
        'ProjectId = Nothing
        'ProductId = Nothing

    End Sub
    Public Overridable Sub ProcessCurrentMasterRecord(ByVal sender As Object, ByVal e As DevExpress.XtraGrid.Views.Base.ValidateRowEventArgs)
        Dim row As DataRow = CType(e.Row, DataRowView).Row
        If IsDBNull(row("Description")) Then
            'this will insert the description with the current week from sunday to saturday
            row("Description") = String.Format("From {0} to {1}", GetDateOfDayOfWeek(DayOfWeek.Sunday).ToString("yyyy-MM-dd"), GetDateOfDayOfWeek(DayOfWeek.Saturday).ToString("yyyy-MM-dd"))
        End If
        'this is set to copy information on detail row for supervised denormalisation
        EmplID = CType(IIf(IsDBNull(row("EmployeeID_FK")), Nothing, row("EmployeeID_FK")), Guid?)
    End Sub
    ''' <summary>
    ''' removed validation on Isnull because those value should always follow user input and are reset on project ressource selection
    ''' The project ressource has precedence on all other values releated, Product, rate , project etc.
    ''' If the user want to override the product it should be done by project ressource.
    ''' Those instruction are for user within Timesheet form of SystemBOX Express
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <param name="index"></param>
    ''' <remarks>Metastring GEN-000009 is used on WorkDescription</remarks>
    Public Overridable Sub ProcessCurrentDetailRecord(ByVal sender As Object, ByVal e As DevExpress.XtraGrid.Views.Base.ValidateRowEventArgs, ByVal index As Integer)
        Dim row As DataRow = CType(e.Row, DataRowView).Row
        'Select Case row.Table.TableName
        '    Case "TimeSheetHourClient"

        DateWorked = CType(IIf(IsDBNull(row("DateWorked")), DateWorked, row("DateWorked")), Date?)

        If IsDBNull(row("WorkDescription")) Then
            row("WorkDescription") = MetaString.GetMetaStringByCode("GEN-000009", AppManager.LanguageId)
        End If

        If IsDBNull(row("DateWorked")) Then
            row("DateWorked") = DateWorked
        End If

        'If IsDBNull(row("ProductId_FK")) Then
        If ProductId.HasValue Then
            row("ProductId_FK") = ProductId.Value
        End If
        'End If

        'If IsDBNull(row("ProjectID_FK")) Then
        If ProjectId.HasValue Then
            row("ProjectID_FK") = ProjectId.Value
        End If
        'End If

        ' If IsDBNull(row("BillingRate")) Then
        If ProjectRessourceRate.HasValue Then
            row("BillingRate") = ProjectRessourceRate.Value
        End If
        ' End If

        If Discount.HasValue Then
            row("Discount") = Discount.Value
        End If

        'Les valeur par défaut si les champs sont NULL - aleblanc 2012-03-06
        If IsDBNull(row("Payable")) Then
            row("Payable") = True
        End If
        '
        If IsDBNull(row("Billable")) Then
            row("Billable") = True
        End If
        '
        If IsDBNull(row("invoiced")) Then
            row("invoiced") = False
        End If


        If Not e.RowHandle = GridControl.NewItemRowHandle Then
            'ici on remet les valeurs a nothing pour ne pas overwriter les valeur déjà entrer pour les lignes suivante - aleblanc
            ProjectRessourceRate = Nothing
            DiscountedRate = Nothing
            Discount = Nothing
            ProjectId = Nothing
            ProductId = Nothing
        End If


        '
        'End Select
    End Sub
    Public Overridable Sub ShownMasterEditor(ByVal sender As Object, ByVal e As EventArgs)
        'Code goes here
    End Sub
    Public Shared Sub HiddenMasterEditor(ByVal sender As Object, ByVal e As EventArgs)
        'TODO : implement a dispose
    End Sub
    Public Overridable Sub ShownDetailEditor(ByVal sender As Object, ByVal e As EventArgs)
        Dim detailView As GridView = CType(sender, GridView)

        If detailView.FocusedColumn.FieldName = "ProjectResourceId_FK" Then
            LookupEdit = CType(detailView.ActiveEditor, GridLookUpEdit)
            CurrentRow = detailView.GetFocusedDataRow()
            If CurrentRow IsNot Nothing Then
                EmplID = If(IsDBNull(CurrentRow("EmplID_FK")), Guid.Empty, CType(CurrentRow("EmplID_FK"), Guid))
            End If
            'End If
            'If ClientMode Then
            LookupEdit.Properties.View.ActiveFilterString = String.Format("EmployeeId_FK = '{0}' and  StatusId_FK <>'{1}'", EmplID.ToString, CommonExt.Base.IdRepository.APP_PROJECTSTATUS_CLOS)
            LookupEdit.Properties.View.OptionsView.ShowFilterPanelMode = Views.Base.ShowFilterPanelMode.Never
            'End If
        End If

    End Sub
    Public Overridable Sub HiddenDetailEditor(ByVal sender As Object, ByVal e As EventArgs)
        'TODO : implement a dispose
        'If LookupEdit IsNot Nothing Then
        '    LookupEdit.Dispose()
        '    LookupEdit = Nothing
        'End If
    End Sub
    Public Overridable Sub InitNewMasterRow(ByVal sender As Object, ByVal e As DevExpress.XtraGrid.Views.Grid.InitNewRowEventArgs)
        Dim view As GridView = CType(sender, GridView)
        Dim row As DataRow = view.GetFocusedDataRow()

        'BestPractice: Don't forget the GUID MUST be generate here.
        'TestPoint
        TimeSheetID = Guid.NewGuid
        row("TimeSheetID") = TimeSheetID
        row("Approved") = 0
        row("EmployeeID_FK") = EmplID
    End Sub
    Public Overridable Sub InitNewDetailRow(ByVal sender As Object, ByVal e As DevExpress.XtraGrid.Views.Grid.InitNewRowEventArgs)
        Dim view As GridView = CType(sender, GridView)
        Dim row As DataRow = view.GetFocusedDataRow()
        Dim parentview As GridView = CType(view.ParentView, GridView)
        Dim parentrow As DataRow = parentview.GetFocusedDataRow


        'ici on remet les valeurs a nothing pour ne pas overwriter les valeur déjà entrer pour les lignes suivante - aleblanc
        ProjectRessourceRate = Nothing
        DiscountedRate = Nothing
        Discount = Nothing
        ProjectId = Nothing
        ProductId = Nothing


        'BestPractice: Don't forget the GUID MUST be generate here.
        'TestPoint
        Using plTsh As SystemBoxSDK.PL.TSMSDK.TimeSheetHour_PL = New SystemBoxSDK.PL.TSMSDK.TimeSheetHour_PL()
            plTsh.NewRecord(row)
            'Pas besoin de l'assigner a cause du DataSet, la relation est dessus
            'row("TimeSheetId_FK") = TimeSheetID
            row("EmplID_FK") = parentrow("EmployeeID_FK")
            row("StatusID_FK") = IdRepository.APP_TIMESHEETHOURSTATUS_PENDING
        End Using

    End Sub
    ''' <summary>
    ''' 
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Public Overridable Sub MenuSubmit(ByVal sender As Object, ByVal e As EventArgs)
        'met la date du jour dans Datasubmitted pis GOGO e-mail
        Dim selectedRow As DataRow = CType(CType(sender, DXMenuItem).Tag, DataRow)
        '
        SystemBoxSDK.PL.TSMSDK.TimeSheet_PL.Submit(selectedRow)
        '
        Dim xrpt As DevExpress.XtraReports.UI.XtraReport = SCIEF.ActiveFramework.CommonExt.RptNotification.GetReportFromDB("TimeSheet")
        '
        Dim sqlcmd As System.Data.SqlClient.SqlCommand = Nothing
        Dim dt As DataTable = New DataTable
        Dim reader As SqlClient.SqlDataReader
        Dim TimeSheedID As Guid = CType(selectedRow("TimeSheetID"), Guid)

        If xrpt IsNot Nothing Then
            Try
                sqlcmd = MetaQuery.GetSPCmdByMetaName("TimeEntryExtended")
                sqlcmd.Parameters("@TimeSheetID").Value = TimeSheedID
                reader = sqlcmd.ExecuteReader(CommandBehavior.CloseConnection)

                dt.Load(reader)
                xrpt.DataSource = dt
            Catch sqlex As System.Data.SqlClient.SqlException
                MessageWindow.ShowMessage(sqlex)
            Finally
                If sqlcmd IsNot Nothing Then
                    sqlcmd.Connection.Close()
                    sqlcmd.Dispose()
                End If
            End Try

            Using msEmailBody As System.IO.MemoryStream = New System.IO.MemoryStream()
                xrpt.ExportToHtml(msEmailBody)
                '
                'On repositionne le stream au début de ca zone mémoire
                'Sinon le Streamreader lit juste a partir de la fin de ca zone memoire, donc rien...
                msEmailBody.Position = 0
                Using streamReader As System.IO.StreamReader = New System.IO.StreamReader(msEmailBody)
                    Dim mail As CommonExt.Utils.EmailExt = New CommonExt.Utils.EmailExt("webmail.scief.com")
                    '
                    mail.From = CommonExt.Base.AppManager.UserName & "@scief.com"
                    mail.To = mail.From
                    mail.Cc = MetaValue.GetMetaValueByCode("OPT_PAYMASTER_EMAIL").Value
                    mail.Subject = "--- TimeSheet Submited ---"
                    mail.Body = streamReader.ReadToEnd
                    mail.Message.IsBodyHtml = True
                    mail.SendMessage()
                End Using
                '
            End Using
        End If
    End Sub

    Public Overridable Sub MenuUnSubmit(ByVal sender As Object, ByVal e As EventArgs)
        Dim selectedRow As DataRow = CType(CType(sender, DXMenuItem).Tag, DataRow)
        SystemBoxSDK.PL.TSMSDK.TimeSheet_PL.UnSubmit(selectedRow)

        Dim mail As CommonExt.Utils.EmailExt = New CommonExt.Utils.EmailExt("webmail.scief.com")
        '
        mail.From = CommonExt.Base.AppManager.UserName & "@scief.com"
        mail.To = mail.From
        mail.Cc = MetaValue.GetMetaValueByCode("OPT_PAYMASTER_EMAIL").Value
        mail.Subject = "--- TimeSheet UnSubmited ---"
        mail.Body = "Time Sheet has been unsubmited"
        mail.Message.IsBodyHtml = True
        mail.SendMessage()
        'clear la datesubmiited pis GOGO e-mail
    End Sub

    Public Overridable Sub MenuReject(ByVal sender As Object, ByVal e As EventArgs)
        Dim selectedRow As DataRow = CType(CType(sender, DXMenuItem).Tag, DataRow)
        SystemBoxSDK.PL.TSMSDK.TimeSheet_PL.Reject(selectedRow)

        Dim mailTo As String = selectedRow("EmailAddress").ToString()

        If Not String.IsNullOrEmpty(mailTo) Then
            Dim mail As CommonExt.Utils.EmailExt = New CommonExt.Utils.EmailExt("webmail.scief.com")
            '
            mail.From = CommonExt.Base.AppManager.UserName & "@scief.com"
            mail.To = mailTo
            mail.Cc = MetaValue.GetMetaValueByCode("OPT_PAYMASTER_EMAIL").Value
            mail.Subject = "--- TimeSheet Rejected ---"
            mail.Body = "Time Sheet has been rejected"
            mail.Message.IsBodyHtml = True
            mail.SendMessage()
            'clear la datesubmiited pis GOGO e-mail
        End If

    End Sub

    Public Overridable Sub MenuReviewed(ByVal sender As Object, ByVal e As EventArgs)
        Dim selectedRow As DataRow = CType(CType(sender, DXMenuItem).Tag, DataRow)
        SystemBoxSDK.PL.TSMSDK.TimeSheet_PL.Reviewed(selectedRow)

        Dim mailTo As String = selectedRow("EmailAddress").ToString()

        If Not String.IsNullOrEmpty(mailTo) Then
            Dim mail As CommonExt.Utils.EmailExt = New CommonExt.Utils.EmailExt("webmail.scief.com")
            '
            mail.From = CommonExt.Base.AppManager.UserName & "@scief.com"
            mail.To = mailTo
            mail.Cc = MetaValue.GetMetaValueByCode("OPT_PAYMASTER_EMAIL").Value
            mail.Subject = "--- TimeSheet Reviewed ---"
            mail.Body = "Time Sheet has been reviewed"
            mail.Message.IsBodyHtml = True
            mail.SendMessage()
            'clear la datesubmiited pis GOGO e-mail
        End If

    End Sub

    Public Overridable Sub MenuApproved(ByVal sender As Object, ByVal e As EventArgs)
        Dim selectedRow As DataRow = CType(CType(sender, DXMenuItem).Tag, DataRow)
        SystemBoxSDK.PL.TSMSDK.TimeSheet_PL.Approve(selectedRow)

        Dim mailTo As String = selectedRow("EmailAddress").ToString()

        If Not String.IsNullOrEmpty(mailTo) Then
            Dim mail As CommonExt.Utils.EmailExt = New CommonExt.Utils.EmailExt("webmail.scief.com")
            '
            mail.From = CommonExt.Base.AppManager.UserName & "@scief.com"
            mail.To = mailTo
            mail.Cc = MetaValue.GetMetaValueByCode("OPT_PAYMASTER_EMAIL").Value
            mail.Subject = String.Format("--- TimeSheet Approuved ---{0} {1}", selectedRow("Description"), selectedRow("username"))
            mail.Body = "Time Sheet has been Approved ---"
            mail.SendMessage()
            'clear la datesubmiited pis GOGO e-mail
        End If

    End Sub

    Public Overridable Sub DeleteRow(ByVal row As DataRow, ByVal e As System.ComponentModel.CancelEventArgs)
        If row.Table.TableName = "TimeSheetClient" Or row.Table.TableName = "TimeSheet" Then
            If DirectCast(row("Approved"), Boolean) = True Then
                e.Cancel = True
                MessageWindow.ShowMessage("Time Sheet is Approved, can't delete it", MsgBoxStyle.Information)
            ElseIf IsDBNull(row("DateSubmited")) = False Then
                e.Cancel = True
                MessageWindow.ShowMessage("Time Sheet is Submited, can't delete it", MsgBoxStyle.Information)
            End If
        End If
    End Sub
    Public Overridable Function GetDateOfDayOfWeek(ByVal dayOfWeek As DayOfWeek) As Date
        Return Now.Subtract(New TimeSpan(Now.DayOfWeek - dayOfWeek, 0, 0, 0))
    End Function

    Public Overridable Sub LookupEdit_CloseUp(sender As Object, e As DevExpress.XtraEditors.Controls.CloseUpEventArgs) Handles LookupEdit.CloseUp
        Dim alookup As GridLookUpEdit = DirectCast(sender, GridLookUpEdit)
        If e.CloseMode <> PopupCloseMode.Cancel AndAlso alookup.Properties.ValueMember = "ProjectResourceId" Then
            Dim agridview As GridView = alookup.Properties.View
            'assign all required value based on Project Ressource selection
            If alookup.Properties.ValueMember = "ProjectResourceId" And e.Value IsNot Nothing Then
                Console.WriteLine(agridview.GetRowCellValue(agridview.FocusedRowHandle, "ProjectName"))
                Console.WriteLine(agridview.GetRowCellValue(agridview.FocusedRowHandle, "PrdDescr_PRM"))

                If Not IsDBNull(agridview.GetRowCellValue(agridview.FocusedRowHandle, "ProjectResourceRate")) Then
                    ProjectRessourceRate = DirectCast(agridview.GetRowCellValue(agridview.FocusedRowHandle, "ProjectResourceRate"), Decimal?)
                Else
                    ProjectRessourceRate = Nothing
                End If

                If Not IsDBNull(agridview.GetRowCellValue(agridview.FocusedRowHandle, "DiscountedRate")) Then
                    DiscountedRate = DirectCast(agridview.GetRowCellValue(agridview.FocusedRowHandle, "DiscountedRate"), Decimal?)
                Else
                    DiscountedRate = Nothing
                End If

                'calcul du discount , précaution pour éviter la division par ZERO

                If ProjectRessourceRate.HasValue AndAlso DiscountedRate.HasValue Then
                    Discount = Round((ProjectRessourceRate.Value - DiscountedRate.Value) / ProjectRessourceRate.Value, 2)
                End If

                ProjectId = CType(agridview.GetRowCellValue(agridview.FocusedRowHandle, "ProjectId"), Guid)
                ProductId = CType(agridview.GetRowCellValue(agridview.FocusedRowHandle, "PrdId"), Guid)
            End If
        End If
    End Sub

    'Public Overridable Sub LookupEdit_CustomDisplayText(sender As Object, e As DevExpress.XtraEditors.Controls.CustomDisplayTextEventArgs) Handles LookupEdit.CustomDisplayText
    '    'Exploration de BDesjardins 2011-12-27


    '    'Dim alookup As GridLookUpEdit = sender
    '    'Dim agridview As GridView = alookup.Properties.View
    '    'If alookup.Properties.ValueMember = "ProjectResourceId" And e.Value IsNot Nothing Then

    '    '    alookup.DisplayText = String.Format("{0} ({1}, {2} ", agridview.GetRowCellValue(agridview.FocusedRowHandle, "ProjectName"), _
    '    '    agridview.GetRowCellValue(agridview.FocusedRowHandle, "SocietyName"), _
    '    '    agridview.GetRowCellValue(agridview.FocusedRowHandle, "PrdDescr_PRM"))

    '    'End If
    'End Sub

    Public Overridable Sub MenuNew(ByVal sender As Object, ByVal e As EventArgs)
        'todo : simulate an Append for creation of new Timesheet header
    End Sub

    Public Overridable Sub Timesheet_CreateHeader(ByVal sender As Object, ByVal e As EventArgs)
        Dim aDialogResult As DialogResult
        Dim sqlcmd As System.Data.SqlClient.SqlCommand = Nothing

        Dim mq As MetaQuery = MetaQuery.GetMetaQueryByName("TimeSheet_CreateAllHeader")

        If mq.MetaParams.Rows.Count > 0 Then

            Dim aParamFrm As MqParamForm = New MqParamForm(mq.QueryName)


            aDialogResult = aParamFrm.ShowDialog()

            'On dit OK pour la form de Parametre
            If aDialogResult = DialogResult.OK Then
                sqlcmd = mq.InitQueryParams

                'On prend les parametre défini par la MQ, pour les retrouver dans le sqlCmd.Parameters
                'Les metaColumns on la priorité
                Dim param As SqlClient.SqlParameter
                For Each row As DataRow In mq.MetaParams.Rows
                    If sqlcmd.Parameters.Contains(row("ColumnName").ToString) Then
                        param = sqlcmd.Parameters(row("ColumnName").ToString)

                        'Get First Day of week from configuration (MetaValue)
                        Dim firstDay As DayOfWeek = CInt(MetaValue.GetMetaValueByCode("OPT_FIRSTDAYOFWEEK").Value)

                        'Validate if Parameter StartDate = first day of week configuration
                        If row("ColumnName").ToString.Contains("StartDate") Then
                            If Not DateTime.Parse(aParamFrm.SelectedParam(row("ColumnName").ToString)).DayOfWeek = firstDay Then
                                MessageWindow.ShowMessage("Start date must be a " + firstDay.ToString + ".")
                                Exit Sub
                            End If
                        End If
                        '
                        ' Set Parameters Values
                        If param IsNot Nothing AndAlso Not IsDBNull(aParamFrm.SelectedParam(row("ColumnName").ToString)) Then
                            param.Value = aParamFrm.SelectedParam(row("ColumnName").ToString)
                        End If
                    Else
                        MessageWindow.ShowMessage(New Exception(String.Format("Report Builder Load, SQL Parameter not found: {0}", row("ColumnName"))))
                    End If
                Next
            End If
            If aDialogResult = DialogResult.OK Then
                mq.FillResultQuery(sqlCmd:=sqlcmd)
                MessageWindow.ShowMessage("Les feuilles de temps ont été créés avec succès.")
            End If
        End If
    End Sub

End Class
